home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / web / noweb / contrib / kostas / lipp.nw (.txt) < prev    next >
LaTeX Document  |  1995-02-24  |  6KB  |  138 lines

  1. \section {The Language-Independent Part}
  2. \label {lipp}
  3. @ The set of characters that may begin an interesting token.
  4. <<Definition of interesting tokens>>=
  5. <<Csets for comment, quote, and special tokens>>
  6. begin_token := res_word_chars ++ begin_comment1 ++ begin_comment2 ++ begin_quote ++
  7.            begin_special
  8. @ These sets contain the {\it initial\/} characters of the corresponding sets of tokens
  9. (strings). The token recognition method used in procedure [[TeXify]] is based on the
  10. assumption that these sets are mutually disjoint, and that they also do not intersect the
  11. set [[id_chars]]. If this assumption does not hold, the results are unpredictable.
  12. <<Csets for comment, quote, and special tokens>>=
  13. begin_comment1 := begin_comment2 := begin_quote := begin_special := ''
  14. every e := !comment1 do begin_comment1 ++:= cset(e[1])
  15. every e := !comment2 do begin_comment2 ++:= cset(e[1][1])
  16. every e := !quote do begin_quote ++:= cset(e[1])
  17. every e := !special do begin_special ++:= cset(e[1])
  18. <<Check that these sets are disjoint>>
  19. \subsection {The procedure TeXify}
  20. Icon's braces for grouping are horrible! Of course, we owe all of this (and more) to C.
  21. <<Procedure [[TeXify]]>>=
  22. procedure TeXify (line)
  23.   <<Local variables>>
  24.   writes("@literal ")
  25.   line ? {if /in_comment then 
  26.         while writes(tab(upto(begin_token))) do
  27.           case &pos+1 of {
  28.         any(id_chars) : <<Identifier>>
  29.         any(begin_special) : <<Possible ``special'' token>>
  30.         any(begin_comment1) : <<Unbalanced comment token>>
  31.         any(begin_comment2) : <<Balanced comment token>>
  32.         any(begin_quote) : <<Quoting token>>
  33.         default: stop("\n** Error in nw.TeXify: pos = ", &pos)
  34.           }
  35.       else
  36.         <<Write comment>>
  37.       writes(tab(0))
  38.   write()
  39.   return
  40. @ All identifiers will be matched (and some non-identifiers, such as explicit numeric
  41. constants), but translations are defined only for reserved words.
  42. <<Identifier>>=
  43. {token := tab(many(id_chars))
  44.  <<Write the translation or the token itself>>}
  45. @ Since the set [[special]] may contain strings which are prefixes of other strings in
  46. [[special]], we can't check for a special token just by [[tab(match(!special))]]. That's
  47. why the set [[S]] is needed.
  48. <<Possible ``special'' token>>=
  49. {token := tab(many(S))
  50.  <<Write the translation or the token itself>>}
  51. @ Output the token and the rest of the line as is, but in [[\rm]] font. Within a comment,
  52. characters special to \TeX\ are active, e.g. \verb+$x^2$+ will produce $x^2$.
  53. <<Unbalanced comment token>>=
  54. {writes(tab(match(!comment1)) || "\\begcom" || tab(0) || "\\endcom")
  55.  break}
  56. @ If we are here, it is not necessarily true that we have found a comment. For example, in
  57. {\sl Mathematica\/} comments begin with a [[(]], which may also appear in [[x+(y+z)]].
  58. <<Balanced comment token>>=
  59. {every c := !comment2 do
  60.    {writes(c_open := tab(match(c[1]))) & c_close := c[2] & break} # Nice Icon style!
  61.  if \c_open then
  62.    {in_comment := "yes"
  63.     writes("\\begcom")
  64.     <<Write comment>>}
  65.  else
  66.    writes(move(1)) # The character wasn't the beginning of a comment.
  67. @ After encountering a quote we write literally, except that we precede every character
  68. special to \TeX\ by a backslash and follow it by an empty group. (This is necessary for
  69. the characters ``\~{}'' and ``\^{}''.)
  70. <<Quoting token>>=
  71. {writes(q := tab(match(!quote))) # The opening quote.
  72.  Q := tab(upto(q))  # The closing quote has to be of the same kind.
  73.  Q ? {while writes(tab(upto(TeXspecial))) do
  74.     writes("\\" || move(1) || "{}")
  75.       writes(tab(0))
  76.      }
  77.  writes(tab(match(!quote))) # The closing quote, hopefully q.
  78. <<Write the translation or the token itself>>=
  79. t := translation[\token]
  80. writes(if \t then t else token)
  81. @ We write literally, but in [[\rm]] font. Within a comment, characters special to \TeX\
  82. are active, e.g. \verb+$x^2$+ will produce $x^2$.
  83. <<Write comment>>=
  84. {if writes(tab(find(c_close))) then
  85.    # Comment ends here.
  86.    {writes("\\endcom" || move(*c_close))
  87.     in_comment := &null}
  88.  else
  89.    # Comment doesn't close on this line.
  90.    writes(tab(0)) 
  91. <<Check that these sets are disjoint>>=
  92. I := begin_comment1 ** begin_comment2 ** begin_quote ** begin_special ** id_chars
  93. if *I ~= 0 then stop ("** nw problem: the characters in the set ", image(I),
  94.                       "\n may begin tokens in more than one category!")
  95. @ [[in_comment]] is [[true]] if we are inside a comment, and [[&null]] otherwise.
  96. [[TeXspecial]] is the set of characters treated specially by \TeX.
  97. <<Local variables>>=
  98. local token, c, t, I, q, Q, c_open
  99. static in_comment, c_close, TeXspecial
  100. initial {TeXspecial := '\\${}&#^_%~'}
  101. <<Global declarations>>=
  102. global translation, id_chars, begin_token, begin_special, S, begin_comment1
  103. global  begin_comment2, begin_quote, special, comment1, comment2, quote
  104. \subsection {Filtering the Input}
  105. @ First we set up the Courier bold font [[\Cb]] (a Postscript font). Then we define the
  106. macro [[\inwcode]] to activate ``[[$]]'' in code sections, and the macro [[\begcom]]
  107. (begin comment) for switching to [[\rm]] font and making the characters ``{\tt\^{}}'', and
  108. ``[[_]]'' active within comments. (``[[$]]'' will also be active within comments, since
  109. they occur only in code sections.)
  110. This section has been written mostly by N. Ramsey.
  111. <<Emit special {\TeX} definitions>>=
  112. write("@literal \\font\\Cb=pcrb ")
  113. write("@literal \\def\\inwcode{\\catcode`\\$=3} ")
  114. write("@literal \\def\\begcom{\\begingroup\\rm\\catcode`\\^=7\\catcode`\\_=8{}} ")
  115. write("@literal \\def\\endcom{\\endgroup} ")
  116. <<Read and filter all the input lines>>=
  117. while line := read() do
  118.   line ? (="@" & filter(tab(upto(' ')|0), if =" " then tab(0) else &null))
  119. <<Procedure [[filter]]>>=
  120. procedure filter (name, arg)
  121.   static kind
  122.   case name of {
  123.     "begin" : {arg ? kind := tab(many(&letters)) 
  124.          copyline(name, arg)
  125.          if kind == "code" then write("@literal \\inwcode")
  126.           }
  127.     "text"  : if \kind == "code" then TeXify(arg) else copyline(name, arg)
  128.     default : copyline(name, arg)
  129.   return
  130. procedure copyline(name, arg)
  131.   return write("@", name, (" " || \arg) | "")
  132. \section{Chunks}
  133. \nowebchunks
  134. %\twocolumn[\section{Index}]
  135. \section{Index}
  136. \nowebindex
  137. \end {document}
  138.